/*
   Copyright (C) 2004/2006/2007/2008 Kai Sterker <kaisterker@linuxgames.com>
   Adapted as C library 2009 Klaus Blindert <klaus.blindert@web.de>

   Originally part of the Adonthell Project http://adonthell.linuxgames.com.
   Part of the libABF project.

   libABF is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, write to the
   Free Software Foundation, Inc.,
   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

/**
 * @file abf_format_xml.c
 * @author Kai Sterker <kaisterker@linuxgames.com>
 * @author Klaus Blindert <klaus.blindert@web.de>
 *
 * @brief Read/write binary-formatted data files.
 */

#include "abf_endians.h"
#include "abf_format_dat.h"
#include "config.h"

#include <stdlib.h>
#include <zlib.h>

abf_flat_t* abf_read_dat(const char* filename)
{
    u_int8 byte_order;
    u_int32 size, checksum;
    char* buffer = 0;
    abf_flat_t* flat = 0;

    gzFile file = gzopen (filename, "rb");
    if (gzread (file, &byte_order, 1) < 1)
    {
        gzclose(file);
        return 0;
    }

    if (gzread (file, &size, 4) < 1)
    {
        gzclose(file);
        return 0;
    }
    size = SwapLE32(size);

    if (byte_order != 'L' && byte_order != 'B')
    {
        gzclose(file);
        return 0;
    }

    buffer = (char*) malloc (size);
    if (gzread (file, (void*) buffer, size) < size)
    {
        free (buffer);
        gzclose (file);
        return 0;
    }

    if (gzread (file, (void*) &checksum, 4) < 4)
    {
        free (buffer);
        gzclose (file);
        return 0;
    }
    gzclose (file);
    checksum = SwapLE32(checksum);

    flat = abf_create();
    abf_flat_setbuffer (flat, buffer, size);

    if (checksum != abf_flat_checksum(flat))
    {
        abf_destroy(flat);
        return 0;
    }
    return flat;
}

void abf_write_dat(abf_flat_t* flat, const char* filename)
{
    u_int32 size, checksum;
    char *buffer;
    abf_flat_getbuffer(flat,&buffer,&size);

    checksum = abf_flat_checksum(flat);
    checksum = SwapLE32(checksum);
    size = SwapLE32(size);

    gzFile file = gzopen (filename, "wb");
    gzputc (file, DATA_BYTE_ORDER);
    gzwrite (file, (void*) &size, 4);
    gzwrite (file, (void*) buffer, size);
    gzwrite (file, (void*) &checksum, 4);
    gzclose (file);
}

